package com.wolfman.socket.server.server;

import com.wolfman.socket.server.pojo.ServerConfig;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @Title
 * @Description
 * @Author WolfMan
 * @Date 2022/11/25 10:11
 * @Email 2370032534@qq.com
 */
public abstract class ServerAbstract {

    private ServerConfig serverConfig;

    private ThreadPoolExecutor executor;

    /**
     * 初始化
     */
    protected void init() {
        this.executor = initServerExecutor();
        this.serverConfig = initServerConfig();
    }

    /**
     * 服务器启动
     */
    public void bootstrap() {
        ServerSocket serverSocket = null;
        try {
            // 绑定监听端口
            serverSocket = new ServerSocket(serverConfig.getPort());
            onServerStart(serverSocket);
            while (true) {
                // 等待客户端连接
                Socket socket = serverSocket.accept();
                onClientConnect(socket);
                // 线程池处理连接
                executor.submit(() -> {
                    BufferedReader reader = null;
                    BufferedWriter writer = null;
                    try {
                        String message = "";
                        reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8));
                        writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), StandardCharsets.UTF_8));
                        while ((message = reader.readLine()) != null) {
                            onClientMessage(socket, message, writer);
                        }
                    } catch (IOException e) {
                        onClientClose(socket, reader, writer);
                    }
                });
            }
        } catch (IOException e) {
            onServerException(e);
        } finally {
            onServerClose(serverSocket);
        }
    }

    /**
     * 服务端启动
     *
     * @param serverSocket
     */
    protected abstract void onServerStart(ServerSocket serverSocket);


    /**
     * 初始化配置
     *
     * @return
     */
    protected abstract ServerConfig initServerConfig();

    /**
     * 初始化线程池
     *
     * @return
     */
    protected abstract ThreadPoolExecutor initServerExecutor();


    /**
     * 服务端关闭
     *
     * @param serverSocket
     */
    protected abstract void onServerClose(ServerSocket serverSocket);

    /**
     * 客户端关闭
     *
     * @param socket
     * @param reader
     * @param writer
     */
    protected abstract void onClientClose(Socket socket, BufferedReader reader, BufferedWriter writer);

    /**
     * 客户端连接
     *
     * @param socket
     */
    protected abstract void onClientConnect(Socket socket);

    /**
     * 服务器异常
     *
     * @param e
     */
    protected abstract void onServerException(IOException e);


    /**
     * 当客户端发送信息
     *
     * @param socket
     * @param msg
     * @param writer
     */
    protected abstract void onClientMessage(Socket socket, String msg, BufferedWriter writer);
}
